#define WINAPI

#include <iostream>
#include <map>
#include "../include/XTFApi.h"

class Spi : public XTFSpi {
   public:
    typedef void(WINAPI* OnStart)(int errorCode, bool isFirstTime);
    typedef void(WINAPI* OnStop)(int errorCode);
    typedef void(WINAPI* OnLogin)(int errorCode, int exchangeCount);
    typedef void(WINAPI* OnLogout)(int errorCode);
    typedef void(WINAPI* OnChangePassword)(int errorCode);
    typedef void(WINAPI* OnReadyForTrading)(const XTFAccount* account);
    typedef void(WINAPI* OnLoadFinished)(const XTFAccount* account);
    typedef void(WINAPI* OnOrder)(int errorCode, const XTFOrder* order);
    typedef void(WINAPI* OnCancelOrder)(int errorCode, const XTFOrder* cancelOrder);
    typedef void(WINAPI* OnTrade)(const XTFTrade* trade);
    typedef void(WINAPI* OnAccount)(int event, int action, const XTFAccount* account);
    typedef void(WINAPI* OnExchange)(int event, int channelID, const XTFExchange* exchange);
    typedef void(WINAPI* OnInstrument)(int event, const XTFInstrument* instrument);
    typedef void(WINAPI* OnBookUpdate)(const XTFMarketData* marketData);
    typedef void(WINAPI* OnEvent)(const XTFEvent& event);
    typedef void(WINAPI* OnError)(int errorCode, void* data, size_t size);

    void* _OnStart;
    void* _OnStop;
    void* _OnLogin;
    void* _OnLogout;
    void* _OnChangePassword;
    void* _OnReadyForTrading;
    void* _OnLoadFinished;
    void* _OnOrder;
    void* _OnCancelOrder;
    void* _OnTrade;
    void* _OnAccount;
    void* _OnExchange;
    void* _OnInstrument;
    void* _OnBookUpdate;
    void* _OnEvent;
    void* _OnError;

    /**
     * API对象启动通知接口
     *
     * 如果API启动后发生连接中断，API会根据配置发起重新连接。
     * 连接成功后，API重新调用onStart接口通知用户，此时isFirstTime为false。
     *
     * 如果API登录后发生连接中断，API重连成功后并不会发起登录请求，需要用户主动发起登录操作。
     *
     * @param errorCode     启动结果。
     *                      0-表示启动成功，可以调用 login() 接口登录柜台；
     *                      X-表示启动失败对应的错误码；
     *
     * @param isFirstTime   是否初次打开。
     *                      可以据此标志位，判断在初次打开时，进行数据的初始化等操作。
     */
    void onStart(int errorCode, bool isFirstTime) override {
        if (_OnStart) {
            ((OnStart)_OnStart)(errorCode, isFirstTime);
        }
    }
    void onStop(int errorCode) override {
        if (_OnStop) {
            ((OnStop)_OnStop)(errorCode);
        }
    }
    void onLogin(int errorCode, int exchangeCount) override {
        if (_OnLogin) {
            ((OnLogin)_OnLogin)(errorCode, exchangeCount);
        }
    }
    void onLogout(int errorCode) override {
        if (_OnLogout) {
            ((OnLogout)_OnLogout)(errorCode);
        }
    }
    void onChangePassword(int errorCode) override {
        if (_OnChangePassword) {
            ((OnChangePassword)_OnChangePassword)(errorCode);
        }
    }
    void onReadyForTrading(const XTFAccount* account) override {
        if (_OnReadyForTrading) {
            ((OnReadyForTrading)_OnReadyForTrading)(account);
        }
    }
    void onLoadFinished(const XTFAccount* account) override {
        if (_OnLoadFinished) {
            ((OnLoadFinished)_OnLoadFinished)(account);
        }
    }
    void onOrder(int errorCode, const XTFOrder* order) override {
        if (_OnOrder) {
            ((OnOrder)_OnOrder)(errorCode, order);
        }
    }
    void onCancelOrder(int errorCode, const XTFOrder* cancelOrder) override {
        if (_OnCancelOrder) {
            ((OnCancelOrder)_OnCancelOrder)(errorCode, cancelOrder);
        }
    }
    void onTrade(const XTFTrade* trade) override {
        if (_OnTrade) {
            ((OnTrade)_OnTrade)(trade);
        }
    }
    void onAccount(int event, int action, const XTFAccount* account) override {
        if (_OnAccount) {
            ((OnAccount)_OnAccount)(event, action, account);
        }
    }
    void onExchange(int event, int channelID, const XTFExchange* exchange) override {
        if (_OnExchange) {
            ((OnExchange)_OnExchange)(event, channelID, exchange);
        }
    }
    void onInstrument(int event, const XTFInstrument* instrument) override {
        if (_OnInstrument) {
            ((OnInstrument)_OnInstrument)(event, instrument);
        }
    }
    void onBookUpdate(const XTFMarketData* marketData) override {
        if (_OnBookUpdate) {
            ((OnBookUpdate)_OnBookUpdate)(marketData);
        }
    }
    void onEvent(const XTFEvent& event) override {
        if (_OnEvent) {
            ((OnEvent)_OnEvent)(event);
        }
    }
    void onError(int errorCode, void* data, size_t size) override {
        if (_OnError) {
            ((OnError)_OnError)(errorCode, data, size);
        }
    }
};
